package com.yonyou.crm.common.field.relation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Service;

/**
 * example 
 * 假设是用户上的性别字段
 * new FieldRelation<UserVO>(UserVO.class, "gender", "genderName", enumService, "gender")
 * @author litcb
 *
 */
@Service
public class EnumFieldRelation<T> extends FieldRelation<T> {
	
	//枚举code
	private String code;
	//要回写的字段
	private String writeField;

	/**
	 * 构造方法
	 * @param clazz 要更改的类
	 * @param readField 要读取的字段
	 * @param writeField 要写入的字段
	 * @param service 枚举服务
	 * @param code 枚举的code
	 */
	public EnumFieldRelation(Class<T> clazz,String readField, String writeField, Object service, String code) {
		super();
		this.clazz = clazz;
		this.readField = readField;
		this.writeField = writeField;
		this.service = service;
		this.code = code;
	}

	@Override
	public List<T> handle(List<T> vos) {
		
		if (vos == null || vos.size() == 0) {
			return vos;
		}
		
		try {
			Field getField = clazz.getDeclaredField(readField);
			getField.setAccessible(true);
			Set<Object> keys = new HashSet<Object>();

			for (T vo : vos) {
				if (vo != null && getField.get(vo) != null) {
					keys.add(getField.get(vo));
				}
			}
			
			Object[] paraValues = keys.toArray(new Object[0]);
			
			if (paraValues == null || paraValues.length == 0) {
				return vos;
			}
			
			Class<?>[] paraTypes = new Class[]{String.class, Object[].class};
			Method selectFieldsByIds = service.getClass().getMethod("selectFieldsByIds", paraTypes);
			//调服务查询结果
			@SuppressWarnings("unchecked")
			List<Map<String, Object>> valueList =  (List<Map<String, Object>>)selectFieldsByIds.invoke(service, new Object[]{code, paraValues});

			if(valueList == null) {
				return vos;
			}
			
			//转换结果集
			Map<String, Object> valueMap = new HashMap<String, Object>();
			for (Map<String, Object> valueObj : valueList) {
				valueMap.put(valueObj.get(Id).toString(), valueObj.get(Name));
			}

			//转换字符串为字段
			Field wField = clazz.getDeclaredField(writeField);
			wField.setAccessible(true);

			//回写字段赋值
			for (T vo : vos) {
				Object valueKeyObj = getField.get(vo);
				if (valueKeyObj != null) {
					wField.set(vo, valueMap.get(valueKeyObj.toString()));
				}
			}
			
		} catch (Exception e) {} 
		
		return vos;
	}
	
	
}
